#include "mainwindow.h"
#include "ui_mainwindow.h"
//#include <QDebug>
#include <QDateTime>
//#define LOG(msg) qDebug() << "[" << __FILE__ << " " << __LINE__ << " " << QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); << "]" << msg

namespace py = pybind11;


MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

//    // 添加python脚本路径
//    _pybind.setScriptPath("../2025_6_22_python");
//    // 加载日志文件
//    bool ret = PyLogFileLoad();
//    if(ret == false)
//    {
//        log("加载日志文件失败！");
//    }
}

MainWindow::~MainWindow()
{
    // 1. 关闭Python日志文件
    if(_fileObj) {
        // 创建局部PyBindC确保GIL被持有
        PyGILState_STATE gstate = PyGILState_Ensure();
        PyLogFileClose();
        PyGILState_Release(gstate);
    }

    // 2. 关闭Python环境（持有GIL）
    Py_Finalize();
//    if(Py_IsInitialized()) {
//        PyGILState_STATE gstate = PyGILState_Ensure();
//        Py_Finalize();
//        PyGILState_Release(gstate);
//    }

    // 3. 最后删除UI对象
    delete ui;
}

void MainWindow::log(const QString msg)
{
    ui->listWidget_log->addItem(msg);
}

void MainWindow::log(const std::string msg)
{
    QString path = __FILE__;
    QString file = path.section("\\", 2, 2);
    QString time = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
    QString totalmsg = "[" + file + ":" + QString::number(__LINE__)  + " " + time + "] ";
    totalmsg += msg.c_str();
    qDebug() << totalmsg;
    log(msg);
}

int MainWindow::PythonCallAdd()
{
    /*Py_Initialize();
    if( !Py_IsInitialized()){
        qDebug() << "python init fail" << endl;
        return 1;
    }
    else
        qDebug() << "python init success" << endl;

    PyRun_SimpleString("import sys");
    PyRun_SimpleString("sys.path.append('../2025_6_22_python')");


    //PyObject* moduleName = PyString_FromString("Add.py");
    PyObject* pModule = PyImport_ImportModule("Add");
    if( pModule == NULL ){
        qDebug() <<"module not found" << endl;
        return 1;
    }
    else
        qDebug() <<"module found" << endl;

    PyObject* pFunc = PyObject_GetAttrString(pModule, "add");
    if( !pFunc || !PyCallable_Check(pFunc)){
        qDebug() <<"not found function Add" << endl;
        return 0;
    }
    else
        qDebug() <<"found function Add" << endl;

    PyObject* args = Py_BuildValue("(ii)", 28, 103);
    PyObject* pRet = PyObject_CallObject(pFunc, args );
    Py_DECREF(args);

    int res = 0;
    PyArg_Parse(pRet, "i", &res );
    Py_DECREF(pRet);
    qDebug() << res << endl;

    Py_Finalize();
    return res;*/
}

void MainWindow::PyCallWriteFile()
{
    /*Py_Initialize();
    // 判断python解析器的是否已经初始化完成
    if(!Py_IsInitialized())
        qDebug()<<"[db:] Py_Initialize fail";
    else
        qDebug()<<"[db:] Py_Initialize success";
    // 执行 python 语句
    PyRun_SimpleString("print('hello world') ");

    // 导入sys模块设置模块地址，以及python脚本路径
    PyRun_SimpleString("import sys");
    // 该相对路径是以build...为参考的
    PyRun_SimpleString("sys.path.append('../2025_6_22_python')");
    // 加载 python 脚本
    PyObject *pModule = PyImport_ImportModule("py_test");  // 脚本名称，不带.py
    if(!pModule)  // 脚本加载成功与否
        qDebug()<<"[db:] pModule fail";
    else
        qDebug()<<"[db:] pModule success";

    // 创建函数指针
    PyObject* pFunc= PyObject_GetAttrString(pModule,"write_file");  // 方法名称
    if(!pFunc || !PyCallable_Check(pFunc))  // 函数是否创建成功
        qDebug()<<"[db:] pFunc fail";
    else
        qDebug()<<"[db:] pFunc success";
    // 调用函数
    PyObject_CallObject(pFunc, NULL);   // 无参调用
    // 并销毁自上次调用Py_Initialize()以来创建并为被销毁的所有子解释器。
    Py_Finalize();*/

}


/*bool MainWindow::PyLogFileLoad()
{
    PyBindC gil;
    // 添加python脚本名字
    bool ret = _pybind.setPModule("logger_module");
    if(ret == false) {
        log("pModule fail");
        return false;
    }
    // 添加python脚本中的函数
    ret = _pybind.setPFunc("log_file_load");
    if(ret == false) {
        log("pFunc fail");
        return false;
    }
    // 调用函数，获取返回值
    PyObject* pRet = _pybind.CallFunc();
    if(pRet == nullptr) {
        log("call function fail");
        return false;
    }
    // 返回值是元组，获取多个返回值
    // 调用PyTuple_GetItem，是借用引用，没有拥有权
    _fileObj = PyTuple_GetItem(pRet, 0);
    // 因此，需要增加计数
    Py_INCREF(_fileObj);

    // 获取log文件路径对象
    PyObject* pfile_path = PyTuple_GetItem(pRet, 1);
    QString file_log = "file_path is ";
    // 先检查类型是否正确
    if(PyUnicode_Check(pfile_path))
    {
        const char* cfile_path = PyUnicode_AsUTF8(pfile_path);
        _filePath += cfile_path;
    }

    int index = _filePath.lastIndexOf('\\');
    if (index != -1) {
        _filePath = _filePath.mid(index + 1); // 从该位置的下一个字符开始到末尾
    }

    file_log += _filePath;
    //PyArg_Parse(pfile_path, "s", cfile_path);
    log(file_log);

    Py_DECREF(pRet);
    return true;
}

bool MainWindow::PyLogFileClose()
{
    bool isSuccess = true;
    // 添加python脚本名字
    bool ret = _pybind.setPModule("logger_module");
    if(ret == false) {
        log("pModule fail");
        return false;
    }
    // 添加python脚本中的函数
    ret = _pybind.setPFunc("log_file_close");
    if(ret == false) {
        log("pFunc fail");
        return false;
    }
    PyObject* pArgs = PyTuple_New(1);
    Py_INCREF(_fileObj); // 窃取引用
    PyTuple_SetItem(pArgs, 0, _fileObj);
    // 调用函数
    PyObject* result = _pybind.CallFunc(pArgs);
    if(!result) {
        log("Failed to call log_file_close function");
        PyErr_Print();  // 打印Python错误信息
        isSuccess = false;
    }
    Py_DECREF(result);  // 释放调用结果

    // 清理资源（无论成功与否）
    if (pArgs) Py_XDECREF(pArgs);

    // 释放文件对象引用（现在只减少一次，因为我们增加了引用）
    Py_XDECREF(_fileObj);
    _fileObj = nullptr;
    return isSuccess;
}

void MainWindow::PyLogByPath(const char* msg)
{
        PyBindC gil;
    bool ret = _pybind.setPModule("logger_module");
    if(ret == false) {
        log("pModule fail");
    }
    ret = _pybind.setPFunc("log_by_path");
    if(ret == false) {
        log("pFunc fail");
    }
    PyObject* pArgs = PyTuple_New(2);
    PyTuple_SetItem(pArgs, 0, PyUnicode_FromString(msg));
    const char* path = _filePath.toUtf8();
    PyTuple_SetItem(pArgs, 1, PyUnicode_FromString(path));

    _pybind.CallFunc(pArgs);
}

void MainWindow::PyLogByObj(const char *msg)
{
        PyBindC gil;
    bool ret = _pybind.setPModule("logger_module");
    if(ret == false) {
        log("pModule fail");
    }
    ret = _pybind.setPFunc("log_by_obj");
    if(ret == false) {
        log("pFunc fail");
    }
    PyObject* pArgs = PyTuple_New(2);
    PyTuple_SetItem(pArgs, 0, PyUnicode_FromString(msg));
    Py_INCREF(_fileObj); // 窃取引用
    PyTuple_SetItem(pArgs, 1, _fileObj);

    _pybind.CallFunc(pArgs);
}*/



void MainWindow::on_pushButton_open_clicked()
{
    int baudrate = 2400;
    ui->comboBox_baudrate->setCurrentText(QString::number(baudrate));

}

void MainWindow::on_pushButton_send_clicked()
{
    PyLogByObj(ui->lineEdit_content->text().toUtf8());
}
